home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
10,000 Great Games
/
10,000 Great Games.iso
/
Product
/
66
/
data1.cab
/
Source_Files
/
Src
/
Primitives.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
2000-01-16
|
5KB
|
247 lines
#include "stdafx.h"
static cSurface *locked_surface;
static DDSURFACEDESC2 desc;
static void (*_pixel)(int x, int y, int color);
void _pixel8(int x, int y, int color)
{
if (x >= 0 && x < locked_surface->w && y >= 0 && y < locked_surface->h)
*((BYTE *)desc.lpSurface + x + y * desc.lPitch) = (BYTE)color;
}
void _pixel16(int x, int y, int color)
{
if (x >= 0 && x < locked_surface->w && y >= 0 && y < locked_surface->h)
*(WORD *)((BYTE *)desc.lpSurface + (x << 1) + y * desc.lPitch) = (WORD)color;
}
void _pixel24(int x, int y, int color)
{
if (x >= 0 && x < locked_surface->w && y >= 0 && y < locked_surface->h)
{
BYTE *d = (BYTE *)desc.lpSurface + (x << 1) + x + y * desc.lPitch;
*(WORD *)d = (WORD)color, d[2] = (BYTE)(color >> 16);
}
}
void _pixel32(int x, int y, int color)
{
if (x >= 0 && x < locked_surface->w && y >= 0 && y < locked_surface->h)
*(DWORD *)((BYTE *)desc.lpSurface + (x << 2) + y * desc.lPitch) = (DWORD)color;
}
void lock_surface_for_primitives(cSurface *surface)
{
desc.dwSize = sizeof(desc);
while (!draw_ok(surface->dds->Lock(0, &desc, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, 0)));
locked_surface = surface;
switch(desc.ddpfPixelFormat.dwRGBBitCount)
{
case 8:
_pixel = _pixel8;
break;
case 16:
_pixel = _pixel16;
break;
case 24:
_pixel = _pixel24;
break;
case 32:
_pixel = _pixel32;
break;
}
}
void unlock_surface_for_primitives()
{
locked_surface->dds->Unlock(0);
}
void pixel(cSurface *surface, int x, int y, int color)
{
// Go to surface coordinates
x = locked_surface->x_screen(x);
y = locked_surface->y_screen(y - surface->start + locked_surface->start);
// Draw the pixel
_pixel(x, y, color);
}
void hline(cSurface *surface, int x1, int y1, int x2, int color)
{
// Go to surface coordinates
x1 = locked_surface->x_screen(x1);
x2 = locked_surface->x_screen(x2);
y1 = locked_surface->y_screen(y1 - surface->start + locked_surface->start);
// x1 is lowest
sort2(x1, x2);
// Draw the line
for (int x = x1; x <= x2; x++)
_pixel(x, y1, color);
}
void vline(cSurface *surface, int x1, int y1, int y2, int color)
{
// Go to surface coordinates
x1 = locked_surface->x_screen(x1);
y1 = locked_surface->y_screen(y1 - surface->start + locked_surface->start);
y2 = locked_surface->y_screen(y2 - surface->start + locked_surface->start);
// y1 is lowest
sort2(y1, y2);
// Draw the line
for (int y = y1; y <= y2; y++)
_pixel(x1, y, color);
}
void rect(cSurface *surface, int x1, int y1, int x2, int y2, int color)
{
hline(surface, x1, y1, x2, color);
hline(surface, x1, y2, x2, color);
vline(surface, x1, y1, y2, color);
vline(surface, x2, y1, y2, color);
}
void rectfill(cSurface *surface, int x1, int y1, int x2, int y2, int color)
{
sort2(y1, y2);
for (int y = y1; y <= y2; y++)
hline(surface, x1, y, x2, color);
}
void line(cSurface *surface, int x1, int y1, int x2, int y2, int color)
{
// Go to surface coordinates
x1 = locked_surface->x_screen(x1);
x2 = locked_surface->x_screen(x2);
y1 = locked_surface->y_screen(y1 - surface->start + locked_surface->start);
y2 = locked_surface->y_screen(y2 - surface->start + locked_surface->start);
// Get size in x and y direction
int sx = abs(x2 - x1), sy = abs(y2 - y1), p;
// Determine how many pixels to write
if (sx > sy)
p = sx;
else
p = sy;
// Check if there is anything to draw
if (p == 0)
return;
// Set initial position and compute delta
fix x = x1, y = y1, dx = (fix)(x2 - x1) / p, dy = (fix)(y2 - y1) / p;
// Draw the line
for (int i = 0; i <= p; i++)
{
_pixel((int)x, (int)y, color);
x += dx, y += dy;
}
}
void dashedline(cSurface *surface, int x1, int y1, int x2, int y2, int color)
{
// Go to surface coordinates
x1 = locked_surface->x_screen(x1);
x2 = locked_surface->x_screen(x2);
y1 = locked_surface->y_screen(y1 - surface->start + locked_surface->start);
y2 = locked_surface->y_screen(y2 - surface->start + locked_surface->start);
// Get size in x and y direction
int sx = abs(x2 - x1), sy = abs(y2 - y1), p;
// Determine how many pixels to write
if (sx > sy)
p = sx >> 2;
else
p = sy >> 2;
// Check if there is anything to draw
if (p == 0)
return;
// Set initial position and compute delta
fix x = x1, y = y1, dx = (fix)(x2 - x1) / p, dy = (fix)(y2 - y1) / p;
// Draw the line
for (int i = 0; i <= p; i++)
{
_pixel((int)x, (int)y, color);
x += dx, y += dy;
}
}
void circle(cSurface *surface, int x, int y, int r, int color)
{
// Go to surface coordinates
x = locked_surface->x_screen(x);
y = locked_surface->y_screen(y - surface->start + locked_surface->start);
// Declare some variables
fix angle;
int dx, dy;
// Pixels to write is 2*Pi*r but we compute only 1/4 of the circle
int p = 11 * r / 7;
// Write circle
for (int i = 0; i <= p; i++)
{
// Step through angle from 0 to 1/2 * Pi = 64 in fixed point
fix angle = (fix)(i * 63 / p);
// Compute location of dot
dx = (int)(cos(angle) * r);
dy = (int)(sin(angle) * r);
// Write 4 dots at once
_pixel(x + dx, y + dy, color);
_pixel(x + dx, y - dy, color);
_pixel(x - dx, y + dy, color);
_pixel(x - dx, y - dy, color);
}
}